//
// Created by antler on 2018/11/8.
//

// 通用命令

#include "lprefix.h"

#include <string>

#include "lua.hpp"
#include "luaext.hpp"

extern "C" {
#include "lstrlib.h"
};

#include <android/log.h>

#include "CommonUtils.h"

static int log(int prio, lua_State *L) {
    std::string tag = luaL_checkstring(L, 1);
    lua_remove(L, 1);

    str_format(L);
    const char *msg = luaL_checkstring(L, -1);

    __android_log_write(prio, tag.c_str(), msg);
    return 0;
}

static int common_log(lua_State *L) {
    const char *msg = luaL_checkstring(L, -1);
    CommonUtils::print(msg);
    return 0;
}

static int common_logv(lua_State *L) {
    log(ANDROID_LOG_VERBOSE, L);
    return 0;
}

static int common_logd(lua_State *L) {
    log(ANDROID_LOG_DEBUG, L);
    return 0;
}

static int common_logi(lua_State *L) {
    log(ANDROID_LOG_INFO, L);
    return 0;
}

static int common_logw(lua_State *L) {
    log(ANDROID_LOG_WARN, L);
    return 0;
}

static int common_loge(lua_State *L) {
    log(ANDROID_LOG_ERROR, L);
    return 0;
}

static int common_print(lua_State *L) {
    std::string msg;

    lua_getglobal(L, "tostring");
    int n = lua_gettop(L);  /* number of arguments */
    for (int i = 1; i <= n - 1; i++) {
        const char *s;
        size_t l;
        lua_pushvalue(L, -1);  /* function to be called */
        lua_pushvalue(L, i);   /* value to print */
        lua_call(L, 1, 1);
        s = lua_tolstring(L, -1, &l);  /* get result */
        if (s == NULL)
            return luaL_error(L, "'tostring' must return a string to 'print'");
        if (i > 1) msg.append("\t");
        msg.append(s, l);
        lua_pop(L, 1);  /* pop result */
    }

    msg.append("\n");

    CommonUtils::print(msg.c_str());
    return 0;
}

static int common_printf(lua_State *L) {
    str_format(L);
    const char *msg = luaL_checkstring(L, -1);
    CommonUtils::print(msg);
    return 0;
}

static int common_sleep(lua_State *L) {
    long timeoutMS = luaL_checklong(L, 1);

    CommonUtils::sleep(timeoutMS);
    return 0;
}

static const luaL_Reg funcs[] = {
        {"log",              common_log},
        {"logv",             common_logv},
        {"logd",             common_logd},
        {"logi",             common_logi},
        {"logw",             common_logw},
        {"loge",             common_loge},
        {"print",            common_print},
        {"printf",           common_printf},
        {"sleep",            common_sleep},
        {nullptr,            nullptr}
};

LUAMOD_API int luaopen_common(lua_State *L) {
    luaL_register(L, "_G", funcs);
    return 0;
}